/*
 *  Color.h
 *  
 *
 *  Created by the same person who made Tuple3, but I
 *  factored out the Color component because it was no
 *  longer a 3-tuple (due to addition of alpha)
 *
 *  Changed by Jason on 2/8/11
 *
 */

class Color
{
public:
    /** The red component. */
    double r;
	
    /** The green component. */
    double g;
	
    /** The blue component. */
    double b;
	
	/** The alpha component. */
	double a;
	
	
    /**
     * Default constructor. Produces black.
     */
    Color ()
    {
        Color(0, 0, 0, 0);
    }
	
	//	
	//    /**
	//     * Copy constructor.
	//     * 
	//     * @param newColor The color to copy.
	//     */
	//    Color (Color newColor)
	//    {
	//        Color(newColor.r, newColor.g, newColor.b);
	//    }
	
	
    /**
     * The explicit constructor.
     * 
     * @param newR The new red value.
     * @param newG The new green value.
     * @param newB The new blue value.
     */
    Color (double newR, double newG, double newB, double newA)
    {
        r = newR;
        g = newG;
        b = newB;
		a = newA;
    }
	
	
    /**
     * Sets this color to the value of inColor.
     * 
     * @param inColor the input color
     */
    void set (Color inColor)
    {
        r = inColor.r;
        g = inColor.g;
        b = inColor.b;
		a = inColor.a;
    }
	
	
    /**
     * Sets the value of this color to (inR, inG, inB)
     * 
     * @param inR the input red value
     * @param inG the input green value
     * @param inB the input blue value
     */
    void set (double inR, double inG, double inB, double inA)
    {
        r = inR;
        g = inG;
        b = inB;
		a = inA;
    }
	
	
    /**
     * Sets this color as the product of the pairwise product of this color and
     * rhs.
     * 
     * @param rhs The right hand argument.
     */
    void scale (Color rhs)
    {
        r *= rhs.r;
        g *= rhs.g;
        b *= rhs.b;
    }
	
	
    /**
     * Scales each compoenent of this color by rhs.
     * 
     * @param rhs The scale value to use.
     */
    void scale (double rhs)
    {
        r *= rhs;
        g *= rhs;
        b *= rhs;
    }
	
	
    /**
     * Sets this color to the pairwise sum of this color and ths.
     * 
     * @param rhs the input color
     */
    void add (Color rhs)
    {
        r += rhs.r;
        g += rhs.g;
        b += rhs.b;
    }
	
	
    /**
     * Adds rhs scaled by scale pairwise to this color.
     * 
     * @param scale the scale factor
     * @param rhs the color to be scaled and added
     */
    void scaleAdd (double scale, Color rhs)
    {
        r += scale * rhs.r;
        g += scale * rhs.g;
        b += scale * rhs.b;
    }
	
	
    /**
     * Clamps the each component of this color to between [min,max]
     * 
     * @param min the minimum value
     * @param max the maximum value
     */
    void clamp (double minimum, double maximum)
    {
        r = max(min(r, maximum), minimum);
        g = max(min(g, maximum), minimum);
        b = max(min(b, maximum), minimum);
    }
	
	
    /**
     * This function returns an int which represents this color. The standard
     * RGB style bit packing is used and is compatible with
     * java.awt.BufferedImage.TYPE_INT_RGB. (ie - the low 8 bits, 0-7 are for
     * the blue channel, the next 8 are for the green channel, and the next 8
     * are for the red channel). The highest 8 bits are left untouched.
     * 
     * @return An integer representing this color.
     */
    int toInt ()
    {
        int iR, iG, iB;
		
        // Here we do the dumb thing and simply clamp then scale.
        // The "+ 0.5" is to achieve a "round to nearest" effect
        // since Java float to int casting simply truncates.
        iR = (int)(255.0 * max(min(r, 1.0), 0.0) + 0.5);
        iG = (int)(255.0 * max(min(g, 1.0), 0.0) + 0.5);
        iB = (int)(255.0 * max(min(b, 1.0), 0.0) + 0.5);
		
        // Bit packing at its finest
        return (iR << 16) | (iG << 8) | (iB << 0);
    }
	
	
    /**
     * @see Object#toString()
     */
	//    string toString ()
	//    {
	//        return "[" + r + "," + g + "," + b + "]";
	//    }
};